﻿namespace SERFLITEMAX20.SocketLib
{
    using System;
    using System.Net;
    using System.Net.Sockets;
    using System.Runtime.CompilerServices;
    using System.Text;

    public class Client
    {
        public string address = "";
        public bool continueUpdate = false;
        public int port = 0x2710;
        public bool runningUpdate = false;
        private Socket server;
        private byte[] TCPdata = new byte[4];

        public event OnErrorEvent ErrorEvent;

        public event OnUpdateEvent UpdateEvent;

        private void Connected(IAsyncResult iar)
        {
            this.server = (Socket) iar.AsyncState;
            try
            {
                this.runningUpdate = true;
                this.server.EndConnect(iar);
                this.server.BeginReceive(this.TCPdata, 0, 4, SocketFlags.None, new AsyncCallback(this.ReceiveData), this.server);
            }
            catch (SocketException exception)
            {
                this.UpdateError(exception);
                this.runningUpdate = false;
                this.server = null;
            }
        }

        public void Dispose()
        {
            this.Stop();
            this.server = null;
        }

        ~Client()
        {
            this.Stop();
        }

        private void ReceiveData(IAsyncResult iar)
        {
            Socket asyncState = (Socket) iar.AsyncState;
            try
            {
                if ((asyncState.EndReceive(iar) == 4) && (BitConverter.ToUInt32(this.TCPdata, 0) == 0xf0f03333))
                {
                    this.TCPdata = new byte[4];
                    if (asyncState.Receive(this.TCPdata, 4, SocketFlags.None) == 4)
                    {
                        int num;
                        int size = BitConverter.ToInt32(this.TCPdata, 0);
                        this.TCPdata = new byte[size];
                        for (int i = asyncState.Receive(this.TCPdata, size, SocketFlags.None); i < size; i += num)
                        {
                            num = asyncState.Receive(this.TCPdata, i, size - i, SocketFlags.None);
                        }
                        this.UpdateMessage(Encoding.ASCII.GetString(this.TCPdata));
                    }
                }
                if (this.runningUpdate)
                {
                    this.TCPdata = new byte[4];
                    this.server.BeginReceive(this.TCPdata, 0, 4, SocketFlags.None, new AsyncCallback(this.ReceiveData), this.server);
                }
            }
            catch (Exception exception)
            {
                this.UpdateError(exception);
            }
        }

        public void Start()
        {
            Socket state = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            IPEndPoint remoteEP = new IPEndPoint(IPAddress.Parse(this.address), this.port);
            this.runningUpdate = true;
            state.BeginConnect(remoteEP, new AsyncCallback(this.Connected), state);
        }

        public void Stop()
        {
            this.runningUpdate = false;
            try
            {
                this.server.Disconnect(false);
            }
            catch
            {
            }
            this.server = null;
        }

        private void UpdateError(Exception ex)
        {
            if (this.ErrorEvent != null)
            {
                this.ErrorEvent(ex.Message);
            }
        }

        private void UpdateMessage(string message)
        {
            if (this.UpdateEvent != null)
            {
                this.UpdateEvent(message);
            }
        }

        public delegate void OnErrorEvent(string error);

        public delegate void OnUpdateEvent(string message);
    }
}

